/*
 * $Id: QECountry.m 249 2008-09-09 13:58:25Z jon $
 * Sleeper
 *
 * Created by Jon Gordon on 3/15/08
 * Copyright Jon Gordon.  All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining 
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including 
 * without limitation the rights to use, copy, modify, merge, publish, 
 * distribute, sublicense, and/or sell copies of the Software, and to 
 * permit persons to whom the Software is furnished to do so, subject to 
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


#import "QECountry.h"

static NSArray *allCountries;

@interface QECountry (private)
+ (QECountry *)findCountryMatchingPredicate:(NSPredicate *)predicate;

- (id)initWithName:(NSString *)newName
          longName:(NSString *)newLongName
       designation:(NSString *)newDesignation
      iso3166_1num:(NSString *)newIso3166_1num
   iso3166_1alpha2:(NSString *)newIso3166_1alpha2
   iso3166_1alpha3:(NSString *)newIso3166_1alpha3
          fips10_4:(NSString *)newFips10_4
      dependencyOf:(QECountry *)newDependencyOf;

- (void)setName:(NSString *)newName;
- (void)setLongName:(NSString *)newLongName;
- (void)setDesignation:(NSString *)newDesignation;
- (void)setIso3166_1num:(NSString *)newIso3166_1num;
- (void)setIso3166_1alpha2:(NSString *)newIso3166_1alpha2;
- (void)setIso3166_1alpha3:(NSString *)newIso3166_1alpha3;
- (void)setFips10_4:(NSString *)newFips10_4;
- (void)setDependencyOf:(QECountry *)newDependencyOf;
@end


@implementation QECountry
+ (void)initialize
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    static BOOL initialized = NO;
    if (!initialized) {
        initialized = YES;
       //// NSLog(@"  initializing");
        qeKeyCountryDesigIndep = [[NSString alloc] initWithString:@"independent"];
        
        NSMutableArray *countries = [[NSMutableArray alloc] init];
        [countries addObject:[[[QECountry alloc] initWithName:@"Canada"
                                                     longName:nil
                                                  designation:qeKeyCountryDesigIndep
                                                 iso3166_1num:@"124"
                                              iso3166_1alpha2:@"CA"
                                              iso3166_1alpha3:@"CAN"
                                                     fips10_4:@"CA"
                                                 dependencyOf:nil] autorelease]];
        [countries addObject:[[[QECountry alloc] initWithName:@"United States"
                                                     longName:@"United States of America"
                                                  designation:qeKeyCountryDesigIndep
                                                 iso3166_1num:@"840"
                                              iso3166_1alpha2:@"US"
                                              iso3166_1alpha3:@"USA"
                                                     fips10_4:@"US"
                                                 dependencyOf:nil] autorelease]];
        
        allCountries = [[NSArray alloc] initWithArray:countries];
        [countries release];
    } // if
} // initialize


+ (NSArray *)allCountries
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return allCountries;
} // allCountries


+ (NSArray *)allIndependentCountries
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"designation LIKE %@", qeKeyCountryDesigIndep];
    return [allCountries filteredArrayUsingPredicate:predicate];
} // allIndependentCountries


+ (QECountry *)countryForName:(NSString *)name
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name LIKE %@", name];
    return [QECountry findCountryMatchingPredicate:predicate];
} // countryForName:


+ (NSArray *)countriesForNames:(NSArray *)names
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:[names count]];
    NSEnumerator *namesEnum = [names objectEnumerator];
    QECountry *country = nil;
    while (nil != (country = [namesEnum nextObject])) {
        [result addObject:country];
    } // while
    return [NSArray arrayWithArray:result];
} // countriesForNames:


+ (QECountry *)countryForIso3166_1num:(NSString *)isoCode
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iso3166_1num LIKE %@", isoCode];
    return [QECountry findCountryMatchingPredicate:predicate];
} // countryForIso3166_1num:


+ (QECountry *)countryForIso3166_1alpha2:(NSString *)isoCode
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iso3166_1alpha2 LIKE %@", isoCode];
    return [QECountry findCountryMatchingPredicate:predicate];
} // countryForIso3166_1alpha2:


+ (QECountry *)countryForIso3166_1alpha3:(NSString *)isoCode
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iso3166_1alpha3 LIKE %@", isoCode];
    return [QECountry findCountryMatchingPredicate:predicate];
} // countryForIso3166_1alpha3


+ (QECountry *)countryForFips10_4:(NSString *)fipsCode
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"fips10_4 LIKE %@", fipsCode];
    return [QECountry findCountryMatchingPredicate:predicate];
} // countryForFips10_4:


- (NSString *)name
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[name retain] autorelease];
} // name

- (NSString *)longName
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[longName retain] autorelease];
} // longName

- (NSString *)designation
{
   //// NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[designation retain] autorelease];
} // designation

- (NSString *)iso3166_1num
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[iso3166_1num retain] autorelease];
} // iso3166_1num

- (NSString *)iso3166_1alpha2
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[iso3166_1alpha2 retain] autorelease];
} // iso3166_1alpha2

- (NSString *)iso3166_1alpha3
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[iso3166_1alpha3 retain] autorelease];
} // iso3166_1alpha3

- (NSString *)fips10_4
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[fips10_4 retain] autorelease];
} // fips10_4

- (QECountry *)dependencyOf
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return [[dependencyOf retain] autorelease];
} // dependencyOf

- (BOOL)isDependency
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    return (nil != [self dependencyOf]);
} // isDependency


- (void)dealloc
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    
    [name release];
    [longName release];
    [designation release];
    [iso3166_1num release];
    [iso3166_1alpha2 release];
    [iso3166_1alpha3 release];
    [fips10_4 release];
    
    [super dealloc];
} // dealloc

- (id)copyWithZone:(NSZone *)zone
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    
    QECountry *newData = [[[self class] allocWithZone:zone]
                          initWithName:[self name] 
                          longName:[self longName]
                          designation:[self designation]
                          iso3166_1num:[self iso3166_1num]
                          iso3166_1alpha2:[self iso3166_1alpha2]
                          iso3166_1alpha3:[self iso3166_1alpha3]
                          fips10_4:[self fips10_4]
                          dependencyOf:[self dependencyOf]];
    return newData;
} // copyWithZone:

- (unsigned int)hash
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    static const unsigned int HASH_BASE = 17;
    static const unsigned int HASH_FACTOR = 37;
    
    unsigned int result = HASH_BASE;
    result = (result * HASH_FACTOR) + [[self name] hash];
    result = (result * HASH_FACTOR) + [[self longName] hash];
    result = (result * HASH_FACTOR) + [[self designation] hash];
    result = (result * HASH_FACTOR) + [[self iso3166_1num] hash];
    result = (result * HASH_FACTOR) + [[self iso3166_1alpha2] hash];
    result = (result * HASH_FACTOR) + [[self iso3166_1alpha3] hash];
    result = (result * HASH_FACTOR) + [[self fips10_4] hash];
    result = (result * HASH_FACTOR) + [[self dependencyOf] hash];
    
    return result;
} // hash

- (BOOL)isEqual:(id)anObject
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    
    return ((self == anObject) ||
            ([[self name] isEqual:[anObject name]] &&
             [[self longName] isEqual:[anObject longName]] &&
             [[self designation] isEqual:[anObject designation]] &&
             [[self iso3166_1num] isEqual:[anObject iso3166_1num]] &&
             [[self iso3166_1alpha2] isEqual:[anObject iso3166_1alpha2]] &&
             [[self iso3166_1alpha3] isEqual:[anObject iso3166_1alpha3]] &&
             [[self fips10_4] isEqual:[anObject fips10_4]] &&
             [[self dependencyOf] isEqual:[anObject dependencyOf]]));
} // isEqual:
@end


@implementation QECountry (private)
+ (QECountry *)findCountryMatchingPredicate:(NSPredicate *)predicate
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    NSArray *matches = [allCountries filteredArrayUsingPredicate:predicate];
    NSAssert2(([matches count] == 0) || ([matches count] == 1),
              @"too many countries (%u) match predicate %@",
              [matches count],
              [predicate predicateFormat]);
    QECountry *result = nil;
    if (1 == [matches count]) {
        result = [matches objectAtIndex:0];
    } // if
    return result;
} // findCountryMatchingPredicate:

- (id)initWithName:(NSString *)newName
          longName:(NSString *)newLongName
       designation:(NSString *)newDesignation
      iso3166_1num:(NSString *)newIso3166_1num
   iso3166_1alpha2:(NSString *)newIso3166_1alpha2
   iso3166_1alpha3:(NSString *)newIso3166_1alpha3
          fips10_4:(NSString *)newFips10_4
      dependencyOf:(QECountry *)newDependencyOf
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    self = [super init];
    if (nil != self) {
        [self setName:newName];
        [self setLongName:newLongName];
        [self setDesignation:newDesignation];
        [self setIso3166_1num:newIso3166_1num];
        [self setIso3166_1alpha2:newIso3166_1alpha2];
        [self setIso3166_1alpha3:newIso3166_1alpha3];
        [self setFips10_4:newFips10_4];
        [self setDependencyOf:newDependencyOf];
    } // if
    return self;
} // initWithName:longName:designation:iso3166_1num:iso3166_1alpha2:iso3166_1alpha3:fips10_4:dependencyOf:

- (void)setName:(NSString *)newName
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (name != newName) {
        [name autorelease];
        name = [newName copy];
    } // if
} // setName:


- (void)setLongName:(NSString *)newLongName
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (longName != newLongName) {
        [longName autorelease];
        longName = [newLongName copy];
    } // if
} // setLongName:

- (void)setDesignation:(NSString *)newDesignation
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (designation != newDesignation) {
        [designation autorelease];
        designation = [newDesignation copy];
    } // if
} // setDesignation:

- (void)setIso3166_1num:(NSString *)newIso3166_1num
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (iso3166_1num != newIso3166_1num) {
        [iso3166_1num autorelease];
        iso3166_1num = [newIso3166_1num copy];
    } // if
} // setIso3166_1num:

- (void)setIso3166_1alpha2:(NSString *)newIso3166_1alpha2
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (iso3166_1alpha2 != newIso3166_1alpha2) {
        [iso3166_1alpha2 autorelease];
        iso3166_1alpha2 = [newIso3166_1alpha2 copy];
    } // if
} // setIso3166_1alpha2:

- (void)setIso3166_1alpha3:(NSString *)newIso3166_1alpha3
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (iso3166_1alpha3 != newIso3166_1alpha3) {
        [iso3166_1alpha3 autorelease];
        iso3166_1alpha3 = [newIso3166_1alpha3 copy];
    } // if
} // setIso3166_1alpha3:

- (void)setFips10_4:(NSString *)newFips10_4
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (fips10_4 != newFips10_4) {
        [fips10_4 autorelease];
        fips10_4 = [newFips10_4 copy];
    } // if
} // setFips10_4:

- (void)setDependencyOf:(QECountry *)newDependencyOf
{
   // NSLog(@"MESSAGE: %s", __PRETTY_FUNCTION__);
    if (dependencyOf != newDependencyOf) {
        [dependencyOf autorelease];
        dependencyOf = [newDependencyOf retain];
    } // if
} // setDependencyOf:
@end
